package com.yuyu.shop.infrastructure.general.mq.listener;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.openservices.ons.api.*;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.yuyu.commons.constant.AliMqPropertiesConstant;
import com.yuyu.commons.constant.BaseConstant;
import com.yuyu.commons.mq.ons.OnsProducer;
import com.yuyu.commons.redis.constant.KeyConstants;
import com.yuyu.commons.redis.util.RedisUtil;
import com.yuyu.shop.api.apimodel.order.dto.OrderCreateDTO;
import com.yuyu.shop.domain.order.DO.OrderCreateDO;
import com.yuyu.shop.domain.order.DO.OrderDO;
import com.yuyu.shop.domain.user.DO.ReceiveInfoDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Set;

/**
 * @author
 * @version 1.0
 * @description: TODO
 * @date 2022/8/30 15:25
 */
@Slf4j
@Component
public class OnsSecKillListener implements MessageListener {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ProducerBean producerBean;


    @Override
    public Action consume(Message message, ConsumeContext consumeContext) {
        //接受消息 创建秒杀订单
        String secKill = new String(message.getBody(), StandardCharsets.UTF_8);
        log.info("秒杀活动穿过来的信息为{}",secKill);
        //todo 应该加一个秒杀表,秒杀订单DO 秒杀订单construct
        try {
            OrderCreateDTO orderCreateDTO = JSON.parseObject(secKill, OrderCreateDTO.class);
            OrderDO orderDO = new OrderDO();
            OrderCreateDO orderCreateDO= orderDO.createOrder(null,orderCreateDTO);
            BeanUtil.copyProperties(orderCreateDO,orderDO);
            //秒杀取默认收货信息
            ReceiveInfoDO defaultReceiveInfo = orderCreateDO.getReceiveInfoDOS().stream().
                    filter(v -> v.getIsDefault().equals(BaseConstant.ONE)).findFirst().get();
            orderDO.setReceiveInfo(defaultReceiveInfo.toString());
            //在redis中设置一个set用来过滤重复的消息
            //先判断是否缓存是否存在
            Set<Object> consumeSet = redisUtil.sGet(KeyConstants.ORDER_SKILL_MQ_CONSUME);
            if (Objects.nonNull(consumeSet)){
                //存在就判断是否消费过
                boolean contains = consumeSet.contains(orderDO.getOrderId());
                if (!contains){
                    orderDO.secKillSaveOrUpdate();
                    redisUtil.sSet(KeyConstants.ORDER_SKILL_MQ_CONSUME,orderDO.getOrderId());
                    log.info("miaoSha创建订单成功!!!!!!!");
                    //发送延迟mq来返回库存
                    Message backStock = new Message();
                    backStock.setTopic(AliMqPropertiesConstant.delayOrderTopic);
                    backStock.setTag(AliMqPropertiesConstant.sKillOrderTag);
                    backStock.setBody(JSON.toJSON(orderDO).toString().getBytes(StandardCharsets.UTF_8));
                    backStock.setStartDeliverTime(60*1000L);
                    producerBean.sendAsync(backStock, new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {

                        }

                        @Override
                        public void onException(OnExceptionContext onExceptionContext) {
                            //todo 未发送成功的消息需要本地实例化 记录为发成功的消息 新建一张未发送成功的表
                        }
                    });
                    log.info("发送时间为{}",System.currentTimeMillis());
                }else {
                    log.info("重复订单,无需消费创建!!!!!");
                }
            }else {
                redisUtil.sSetAndTime(KeyConstants.ORDER_SKILL_MQ_CONSUME,60*60L);
            }
            return Action.CommitMessage;
        }catch (Exception e){
            log.error("secKill consume is failed",e);
            return Action.ReconsumeLater;
        }
    }
}
